package org.jground.rx.ui.zk.viewControl;

import java.util.Collection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jground.rx.IRXObject;
import org.jground.rx.IRXObjectSynopsis;
import org.jground.rx.IRXObjectUtils;
import org.jground.rx.RX;
import org.jground.rx.RXAttribute;
import org.jground.rx.RXTypeComponent;
import org.jground.rx.RXView;
import org.jground.rx.ui.zk.UIEditPanel;
import org.jground.rx.ui.zk.UIFrame;
import org.jground.rx.ui.zk.UIResultList;
import org.jground.util.ArrayUtils;
import org.jground.zk.zulX.DivX;
import org.jground.zk.zulX.HboxX;
import org.jground.zk.zulX.VboxX;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Button;
import org.zkoss.zul.Listcell;

public class UIAttributeControlComponent extends UIAttributeControlBase implements EventListener {

    private static Log logger = LogFactory.getLog(UIAttributeControlComponent.class);

    public UIAttributeControlComponent createNew(UIFrame uiFrame, RXView moControl) {
        return new UIAttributeControlComponent(uiFrame, moControl);
    }

    public UIAttributeControlComponent() {}

    // private static String DELETE = "Delete", EDIT = "Edit";

    // RX
    private RXAttribute moAttribute;
    private String compMoid;
    // LIST DATA
    private UIResultList uiResultList;
    private boolean isMultiple;
    private boolean isInline;
    private UIEditPanel uiEditPanel;
    private DivX div;
    private HboxX buttonPanel;
    private Button newBt;
    private Button doneBt;
    private Button cancelBt;
    private Button deleteBt;
    private boolean isEditPanelOpen;
    private IRXObject currentModOnEdit;

    //

    private UIAttributeControlComponent(UIFrame uiFrame, RXView moControl) {

        super(uiFrame, moControl);
        this.moAttribute = moControl.getRXAttribute();

        RXTypeComponent moTypeComp = (RXTypeComponent) moAttribute.getRXType().getBaseType();
        compMoid = moTypeComp.getLookupMoid();
        isMultiple = moAttribute.getRXType().isMultiple();
        isInline = RX.AttValue.true_.equals(moControl.getPropertyWithDefault(RX.AttName.inline, "false"));
        isInline = isInline && !isMultiple;
        //
        uiEditPanel = new UIEditPanel(uiFrame, compMoid);
        div = new DivX();
        div.setStyle("width:100%;border: green 0px solid");

        if (isInline) {
            div.set(uiEditPanel.getView());
            add(div);
        } else {
            //
            uiResultList = new UIResultList(uiFrame);
            SelectionListener renderer = new SelectionListener();
            // uiResultList.setPostfixRenderer(renderer);
            uiResultList.setExternalEventListener(renderer);
            //
            newBt = new Button("New");
            doneBt = new Button("Done");
            cancelBt = new Button("Cancel");
            deleteBt = new Button("Delete");
            buttonPanel = UIHelper.createButtonPanel();
            //
            add(new VboxX(UIResultList.uiBox(uiResultList), div, buttonPanel));
            //
            doneBt.addEventListener(Events.ON_CLICK, this);
            cancelBt.addEventListener(Events.ON_CLICK, this);
            deleteBt.addEventListener(Events.ON_CLICK, this);
            newBt.addEventListener(Events.ON_CLICK, this);
            //
            closeEditPanel();
        }
    }

    @Override
    public void set(String... values) {
        clear();
        IRXObject modContext = getDataContext();
        //
        // INLINE
        //
        if (isInline) {
            if (ArrayUtils.isNotEmpty(values)) {
                IRXObject mod = modContext.getComponentById(values[0]);
                if (mod != null) {
                    uiEditPanel.setData(mod);
                } else {
                    uiEditPanel.setData(modContext.newComponent(moAttribute.getName()));
                }
            } else {
                uiEditPanel.setData(modContext.newComponent(moAttribute.getName()));
            }
        } else {
            //
            //
            //
            if (ArrayUtils.isNotEmpty(values)) {
                for (String oid : values) {
                    IRXObject mod = modContext.getComponentById(oid);
                    if (mod != null) {
                        uiResultList.addObjects(mod);
                    } else {
                        logger.error("no IRXObject found with: " + oid);
                    }
                }
            }
            closeEditPanel();
        }
    }

    @Override
    public String[] get() {
        if (isInline) {
            // IRXObject modContext = getDataContext();
            IRXObject mod = uiEditPanel.getData();
            // modContext.addToCompCache(mod);
            return IRXObjectUtils.toOidStringArray(mod);
        } else {
            update();
            Collection<IRXObjectSynopsis> compMods = uiResultList.getObjects();
            return IRXObjectUtils.toOidStringArray(compMods);
        }
    }

    @Override
    public void clear() {
        if (isInline) {
            uiEditPanel.clearData();
        } else {
            uiResultList.removeAllObject();
        }
    }

    public void onEvent(Event he) {
        if (he.getTarget() == newBt) {
            // currentModOnEdit = IRXObject.create(compMoid);
            IRXObject modContext = getDataContext();
            currentModOnEdit = modContext.newComponent(this.moAttribute.getName());
            uiEditPanel.setData(currentModOnEdit);
            openEditPanel();
        }
        if (he.getTarget() == doneBt) {
            update();
            closeEditPanel();
            currentModOnEdit = null;
        }
        if (he.getTarget() == cancelBt) {
            closeEditPanel();
            currentModOnEdit = null;
        }
        if (he.getTarget() == deleteBt) {
            closeEditPanel();
            uiResultList.removeObject(currentModOnEdit);
            currentModOnEdit = null;
        }
    }

    private void openEditPanel() {
        div.set(uiEditPanel.getView());
        buttonPanel.set(doneBt, deleteBt, cancelBt);
        isEditPanelOpen = true;
        uiFrame.invalidate();
    }

    private void closeEditPanel() {
        uiEditPanel.clearData();
        div.removeAll();
        buttonPanel.removeAll();
        if (isMultiple || uiResultList.objectCount() == 0) {
            buttonPanel.set(newBt);
        }
        isEditPanelOpen = false;
        uiFrame.invalidate();

    }

    private boolean isEditPanelOpen() {
        return isEditPanelOpen;
    }

    public Collection<IRXObjectSynopsis> getMoDataObjects() {
        return uiResultList.getObjects();
    }

    void update() {
        logger.debug("this: " + this);
        if (isEditPanelOpen()) {
            // IRXObject modContext = getDataContext();
            IRXObject mod = uiEditPanel.getData();
            // modContext.addToCompCache(mod);
            if (isMultiple) {
                uiResultList.addObjects(mod);
            } else {
                uiResultList.removeAllObject();
                uiResultList.addObjects(mod);
            }
        }
    }

    public class SelectionListener implements EventListener {

        public void onEvent(Event h) {
            if (h.getTarget() instanceof Listcell) {
                Listcell cell = (Listcell) h.getTarget();
                Long oid = (Long) cell.getAttribute("oid");
                IRXObject modContext = getDataContext();
                currentModOnEdit = modContext.getComponentById(oid);
                uiEditPanel.setData(currentModOnEdit);
                openEditPanel();
            }
        }

    }

}